﻿using System;
using System.Collections.Generic;
using System.Text;

namespace System.Data.SugarClient.Soap.V1
{
	internal class V1SetEntryAction : V1ModuleAction
	{

		#region Constructors

		internal V1SetEntryAction(
			SugarSoapV1.sugarsoap service,
			string session,
			string moduleName,
			IDictionary<string, object> values)
			: base(service,session, moduleName) 
		{
			this._values = values;
			string[] unavailablefields = CheckFieldAvailablility();
			if (0 < unavailablefields.Length)
			{
				StringBuilder builder = new StringBuilder();
				foreach (string unavailablefield in unavailablefields) { builder.AppendFormat("{0},", unavailablefield); }
				throw new SugarException(string.Format("Field {0} is not available at {1} module.", builder.ToString(), this.Module));
			}
		}

		#endregion

		#region Fields

		private readonly IDictionary<string, object> _values;

		#endregion

		#region Properties

		public IDictionary<string, object> Values
		{
			get { return _values; }
		}

		#endregion

		protected override V1ActionResult ExecuteInner()
		{
			var result = 
				this.SoapService.set_entry(
					this.Session,
					this.Module,
					this.ToNameValueArray(this.Values));

			return new V1SetEntryActionResult(this, result);
		}

		internal SugarSoapV1.name_value[] ToNameValueArray(
			IDictionary<string, object> values)
		{
			List<SugarSoapV1.name_value> namevalues = new List<SugarSoapV1.name_value>();
			foreach (string key in values.Keys)
			{
				//if (key.Equals("assign"))
				//{
				//  bool accountid_autofill = false;
				//  if (values[key] == null) accountid_autofill = true;
				//  if (string.IsNullOrEmpty(values[key].ToString())) accountid_autofill = true;

				//  if (accountid_autofill)
				//  {
				//    V1GetUserIdActionResult result = new V1GetUserIdAction(this.SoapService, this.Session).Execute() as V1GetUserIdActionResult;
				//    values[key] = result.Id;
				//  }
				//}
				namevalues.Add(new System.Data.SugarClient.SugarSoapV1.name_value() { name = key, value = values[key].ToString() });
			}
			return namevalues.ToArray();
		}

		internal protected string[] CheckFieldAvailablility()
		{
			V1GetModuleFieldsAction action = new V1GetModuleFieldsAction(this.SoapService, this.Session, this.Module);
			V1GetModuleFieldsActionResult result = action.Execute() as V1GetModuleFieldsActionResult;
			if (!result.Success) throw new SugarException("Can not get field list");
			List<string> target = new List<string>(this.Values.Keys);
			foreach (SugarVarDef vardef in result.VarDefs)
			{
				target.Contains(vardef.Name);
				target.Remove(vardef.Name);
				if (target.Count == 0) return new string[]{};
			}

			if (0 < target.Count) return target.ToArray();
			else return new string[] { };
		}
	}

	internal class V1SetEntryActionResult : V1ModuleActionResult, ISetEntryActionResult
	{

		internal V1SetEntryActionResult(
			V1SetEntryAction action,
			SugarSoapV1.set_entry_result result)
			: base(action)
		{
			this._result = result;
		}

		private readonly SugarSoapV1.set_entry_result _result;

		#region Properties

		internal SugarSoapV1.set_entry_result SoapResult
		{
			get { return _result; }
		}

		public string Id
		{
			get { return this.SoapResult.id; }
		}

		#endregion

		public override bool Success
		{
			get
			{
				if (SoapResult.error == null) return true;
				else if (SoapResult.error.number == null) return true;
				else if ("0".Equals(SoapResult.error.number)) return true;
				else return false;
			}
		}

	}
}
